package conversion;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Odczytuje pliki logow z formy tekstowej i zamienia na bardziej uzyteczna w
 * postaci obiektow javy
 * 
 * @author Marcin
 * 
 */
public class RequestsSet {// implements Iterable<Request> {
	private final File file;

	public RequestsSet(File file) {
		if (file == null)
			throw new NullPointerException("file");

		this.file = file;
	}

	public List<Request> getRequests() throws IOException {
		BufferedReader in = null;
		try {
			in = new BufferedReader(new FileReader(this.file));

			String line;
			List<Request> result = new ArrayList<Request>();

			while ((line = in.readLine()) != null) {
				result.add(Request.createRequest(line));
			}

			return result;
		} finally {
			if (in != null)
				in.close();
		}
	}

	/**
	 * Funkcja ze zbioru zadan wyodrebnia uzytkownikow oraz ich sesje i
	 * dostarcza informacje o nich w postaci obiektu
	 * RequestsSessionsUsersStructure.
	 * 
	 * @param secondsSeparator
	 * @return
	 * @throws IOException
	 */
	public RequestsSessionsUsersStructure getUserSessions(int secondsSeparator)
		throws IOException {

		Map<String, List<Request>> usersRequestsMap =
			new HashMap<String, List<Request>>();

		System.out.println("identifying users");
		for (Request r : this.getRequests()) {
			String ip = r.getRequesterIP();
			if (!usersRequestsMap.containsKey(ip)) {
				usersRequestsMap.put(ip, new ArrayList<Request>());
			}

			usersRequestsMap.get(ip).add(r);
		}

		System.out.println("making user objects");
		List<User> users = new ArrayList<User>(usersRequestsMap.size());
		for (Map.Entry<String, List<Request>> entry : usersRequestsMap.entrySet()) {
			users.add(new User(entry.getKey(), entry.getValue(),
				secondsSeparator));
		}
		return new RequestsSessionsUsersStructure(users);
	}

	public static void main(String[] args) throws IOException {

		RequestsSet rs =
			new RequestsSet(
				new File(
					"e:/studia/eksploracja-danych/lab/zad1/log/access_log_utf8_out"));
		System.out.println("start");
		RequestsSessionsUsersStructure userSessions =
			rs.getUserSessions(60 * 30);
		// List<Request> requests = rs.getRequests();
		System.out.println("end");

		for (Session s : userSessions.getSessions()) {
			System.out.println(s);
		}
		// for(User u : userSessions.getUsers()) {
		// System.out.println(u);
		//			
		// }
	}

	/**
	 * Filtruje linijki zadan z pliku input i przepisuje do pliku output. Kryteria filtracji to:
	 * 
	 * - zakonczenie sukcesem (kod 200)
	 * 
	 * - zadanie strony html
	 * 
	 * - metoda GET
	 * 
	 * 
	 * @param input
	 * @param output
	 * @throws IOException
	 */
	public static void filterLines(File input, File output) throws IOException {

		BufferedReader in = null;
		BufferedWriter out = null;
		try {
			in = new BufferedReader(new FileReader(input));
			out = new BufferedWriter(new FileWriter(output));

			String line;
			int i = 0;
			while ((line = in.readLine()) != null) {
				Request r = Request.createRequest(line);
				if (r != null && r.getStatus() == 200
					&& r.getMethod().equals("GET") && r.isResourceHtmlPage()) {

					out.write(line);
					out.write("\n");

					if (i % 1000 == 0)
						System.out.println(i);

					i++;
				}
			}
		} finally {
			if (in != null)
				in.close();
			if (out != null)
				out.close();
		}
	}
}

//
// @Override
// public Iterator<Request> iterator() {
//
// BufferedReader br = null;
//
// try {
//
// br = new BufferedReader(new FileReader(this.file));
// final BufferedReader in = br;
// return new Iterator<Request>() {
// private String line = in.readLine();
//
// @Override
// public boolean hasNext() {
// return line != null;
// }
//
// @Override
// public Request next() {
// Request r = Request.createRequest(line);
// try {
// this.line = in.readLine();
// } catch (IOException e) {
// e.printStackTrace();
// throw new Error(e);
// }
// return r;
// }
//
// @Override
// public void remove() {
// throw new UnsupportedOperationException();
// }
//
// };
// } catch (FileNotFoundException e) {
// e.printStackTrace();
// throw new Error(e);
// } catch (IOException e) {
// e.printStackTrace();
// throw new Error(e);
// } finally {
// if (br != null)
// try {
// br.close();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
// }